#include "../lib/common.h"
#include <sys/wait.h>

#define MAX_LINE 4095

char rot13_char(char c)
{
  if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
    return c + 13;
  else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
    return c - 13;
  else
    return c;
}

void child_run(int fd)
{
  char outbuf[MAX_LINE + 1];
  size_t outbuf_used = 0;
  ssize_t result;

  while (1)
  {
    char ch;
    result = recv(fd, &ch, 1, 0);
    if (result == 0)
    {
      break;
    }
    else if (result == -1)
    {
      perror("read");
      break;
    }
    if (outbuf_used < sizeof(outbuf))
    {
      outbuf[outbuf_used++] = rot13_char(ch);
    }

    if (ch == '\n')
    {
      send(fd, outbuf, outbuf_used, 0);
      outbuf_used = 0;
      continue;
    }
  }
}

void sigchld_handler(int sig)
{
  while (waitpid(-1, 0, WNOHANG) > 0)
    ;
  return;
}

int main(int argc, char const *argv[])
{
  int listen_fd = tcp_server_listen(1024);
  signal(SIGCHLD, sigchld_handler);
  while (1)
  {
    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);
    int fd = accept(listen_fd, (struct sockaddr *)&ss, &slen);
    if (fd < 0)
    {
      error(1, errno, "accept failed");
      exit(1);
    }

    // == 0 则是子进程的逻辑
    if (fork() == 0)
    {
      // 在子进程中，不需要关心监听端口，故关掉
      close(listen_fd);
      child_run(fd);
      exit(0);
    }
    else
    {
      close(fd);
    }
  }

  return 0;
}
